#pragma once
#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<queue>
#include<mutex>
using namespace std;
template <class T>
class Block_Queue
{
public:
    Block_Queue()
    {
        max_size = 5;
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_pcond,nullptr);
        pthread_cond_init(&_ccond,nullptr);
    }
    ~Block_Queue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_pcond);
        pthread_cond_destroy(&_ccond);
    } 
    void push(T& cnt)
    {
        pthread_mutex_lock(&_mutex);
        while(_is_full())
        {
            //满了就要等待
            pthread_cond_wait(&_pcond,&_mutex);
        }
        //此时肯定不是满的
        _block.push(cnt);
        pthread_cond_signal(&_ccond);
        pthread_mutex_unlock(&_mutex);

    }
    void pop(T* out)
    {
        pthread_mutex_lock(&_mutex);
        while(_is_empty())
        {
            //空了就要等待
            pthread_cond_wait(&_ccond,&_mutex);
        }
        //此时肯定不是满的
        *out = _block.front();
        _block.pop();
        pthread_cond_signal(&_pcond);
        pthread_mutex_unlock(&_mutex);

    }
private:
    queue<T> _block;
    int max_size;
    pthread_mutex_t _mutex;
    pthread_cond_t _pcond;
    pthread_cond_t _ccond;
    bool _is_empty()
    {
        return _block.empty();
    }
    bool _is_full()
    {
        return _block.size() == max_size;
    }
    
};
